home *** CD-ROM | disk | FTP | other *** search
- /*
- Sherlock utility routines.
-
- source: sl_util.c
- started: November 4, 1993.
- version: March 12, 1996.
- */
-
- #include <LIBlib.h>
- #include <LIBend.h>
-
- #include <sl.h>
- #include <sl2.h>
-
- #include <ctype.h>
- #include <stdlib.h>
- #include <string.h>
-
- #ifdef applec
- #include <SegLoad.h>
- #include <OSUtils.h>
- #endif
-
- /*
- Abort Sherlock.
-
- This is to be called if an error prevents Sherlock from being initialized.
- Assume nothing is available that must be initialized.
- */
- void
- sl_abort(int beeps)
- {
-
- #if defined(THINK_C) || defined(SYMANTEC_C) || defined(__MWERKS__)
- int i;
- for (i = 0; i < beeps; i++) {
- SysBeep(20);
- }
- #endif
-
- end_abort();
- }
-
- /*
- Function prototypes of internal routines.
- */
- static int sl_hash (char *);
-
- /*
- Return the name on the call stack n levels back.
- */
- char *
- sl_callname(int n)
- {
- register sl_snode * sp;
-
- if (n < 0 || (sl_level - n - 1 < 0) || sl_stack == NULL) {
- return "";
- }
- else {
- char * the_name;
- sp = &sl_stack [sl_level - n - 1];
- the_name = sp -> node -> name;
- return (the_name[0] == '!' || the_name[0] == '+') ? the_name+1 : the_name;
- }
- }
-
- /*
- SL_CLEAR macro--Clear all statistics.
- */
- void
- sl_clear(void)
- {
- register int i;
- register sl_node * p;
-
- /* 5/19/92 */
- if (sl_htab == NULL) {
- return;
- }
- for (i = 0; i < SL_MAX_HASH; i++) {
- for (p = sl_htab[i]; p; p = p -> next) {
- p -> time = 0;
- p -> time2 = 0;
- p -> calls = 0;
- }
- }
- }
-
- /*
- Check the string arguments to a tracing function.
-
- The sl_cname global variable points to a string containing the
- name of the macro responsible for invoking the check.
- */
- void
- sl_check(register char *s)
- {
- register char c;
- register int i;
- char *old_s;
-
- old_s = s;
-
- /* Check for null string. */
- if (!*s) {
- es("sl_check: "); es(sl_cname);
- es(": null string @ "); eptr(s); enl();
- sl_exit();
- }
-
- /* Skip over ! and - characters. */
- if (*s == '!' || *s == '-') {
- s++;
- }
- if (*s == '!' || *s == '-') {
- s++;
- }
-
- /* 6/27/89: allow up to 31 character names. */
- for (i = 0; i < 31; i++) {
- c = *s++;
- if (c == '\0') {
- return ;
- }
-
- /* Allow only identifiers and wild cards. */
- if (!isalnum(c) && c != '_' && c != '*' && c != '?') {
- es("sl_check: "); es(sl_cname);
- es(": bad character: "); echar(c);
- es(" in "); es(old_s);
- es(" @ "); eptr(s); enl();
- sl_exit();
- }
- }
-
- es("sl_check: "); es(sl_cname);
- es(": run on argument: "); es(old_s);
- es(" @ "); eptr(s); enl();
- sl_exit();
- }
-
- /*
- Print out n periods.
- */
- void
- sl_dots(n)
- int n;
- {
- int i;
-
- ecnl();
- if (!sl_nodots) {
- for(i = 0; i < n+1; i++) {
- echar('.');
- }
- }
- }
-
- /*
- Do whatever is necessary to terminate Sherlock.
- */
- void
- sl_exit(void)
- {
-
- #if defined(THINK_C) || defined(SYMANTEC_C) || defined(__MWERKS__)
- SysBeep( 5L );
- es("Press the mouse to continue...\n");
- while(!Button()) {
- ;
- }
- ExitToShell();
- #else
- exit(1);
- #endif
-
- }
-
- /*
- Return a pointer to the node for s.
- Set the global sl_cname to macro_type.
- This is for internal use only.
- Users should use sl_findname in macro.c.
- */
-
- sl_node *
- sl_find(char *macro_type, char *s)
- {
- register int i;
- register sl_node *p, *q, *node;
- register int hash;
-
- /* 5/19/92 */
- if (sl_htab == NULL) {
- sl_abort(SL_ABORT_FIND);
- }
-
- /* Update global error string. */
- if (macro_type != NULL) {
- sl_cname = macro_type;
- }
-
- /* Skip over ! and - characters. */
- if (*s == '!' || *s == '-') {
- s++;
- }
- if (*s == '!' || *s == '-') {
- s++;
- }
-
- /* Search the proper index table. */
- hash = sl_hash(s);
- p = sl_htab [hash];
- if (p != NULL) {
- i = strcmp(s, p -> name);
- if (i == 0) {
- return p;
- }
- }
- if (p == NULL || i < 0) {
- sl_check(s);
- node = sl_new(s);
- sl_htab [hash] = node;
- node -> next = p;
- return node;
- }
-
- /* Search the list for the node. */
- for (q = p, p = p -> next; p; q = p, p = p -> next) {
- i = strcmp(s, p -> name);
- if (i == 0) {
- return p;
- }
- else if (i < 0) {
- break;
- }
- }
-
- /* Not found. */
- sl_check(s);
- node = sl_new(s);
- q -> next = node;
- node -> next = p;
- return node;
- }
-
- /*
- Compute hash code for the string s.
- */
- static int
- sl_hash(register char *s)
- {
- register unsigned int hash = 0;
-
- while (*s) {
- hash += hash + hash + (unsigned int) *s++;
- hash %= SL_MAX_HASH;
- }
- return (int) hash;
- }
-